package appapi.service.impl;

import appapi.Vo.bigScreen.EquipTypeTreeVo;
import appapi.dto.basic.EquipTypeVo;
import appapi.dto.basic.GenerateImportDto;
import appapi.utils.OrderUtils;
import appapi.utils.RedisUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.google.common.util.concurrent.AtomicDouble;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import appapi.dao.EquipmenttypeMapper;
import appapi.entity.basic.EquipmenttypeEntity;
import appapi.service.EquipmenttypeService;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 请求对象
 *
 * @author luocheng
 * @version 1.0
 * @date 2023/05/27 16:32
 */
@Service
public class EquipmenttypeServiceImpl implements EquipmenttypeService {

    @Resource
    private EquipmenttypeMapper equipmenttypeMapper;
    @Autowired
    private RedisUtils redisUtils;
//    @Autowired
//    private RedisRepository redisUtils;

    @Override
    public int deleteByPrimaryKey(Long equipTypeId) {
        return equipmenttypeMapper.deleteByPrimaryKey(equipTypeId);
    }

    @Override
    public int insert(EquipmenttypeEntity record) {
        return equipmenttypeMapper.insert(record);
    }

    @Override
    public int insertSelective(EquipmenttypeEntity record) {
        return equipmenttypeMapper.insertSelective(record);
    }

    @Override
    public EquipmenttypeEntity selectByPrimaryKey(Long equipTypeId) {
        return equipmenttypeMapper.selectByPrimaryKey(equipTypeId);
    }

    @Override
    public List<EquipmenttypeEntity> queryList(String equipTypeName) {
        return equipmenttypeMapper.queryList(equipTypeName);
    }

    @Override
    public int count(EquipmenttypeEntity record) {
        return equipmenttypeMapper.count(record);
    }

    @Override
    public int updateByPrimaryKeySelective(EquipmenttypeEntity record) {
        return equipmenttypeMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(EquipmenttypeEntity record) {
        return equipmenttypeMapper.updateByPrimaryKey(record);
    }

    @Override
    public List<Map<String, Object>> getTypeList() {
        return equipmenttypeMapper.selectList();
    }

    @Override
    public GenerateImportDto importTypeList(List<EquipTypeVo> voList) {
        // 1、项目编号：年(2位)+月+日+时+分+6位随机数，如：2108111050123456。
        // 2、拼接Redis键值：kdzn:import:recharge_项目编号
        // 3、验证：
        // 数据的完整性：类别名称、大类名称是否有值。提示：数据不完整
        // 数据的重复性：同一类别只有一条记录。提示“类别XXX的记录重复”
        // 数据的重复性：数据库是否存在类别。提示“类别XXX的已存在”
        // 4、存储到reids中，有效期为30分钟。
        // 5、数据结构：Redis自增ID，设备类型，大类名称、特种设备，是否错误，错误提示。
        // Redis自增ID，作为记录的唯一值，可进行编辑和删除。
        // 1、项目编号：年(2位)+月+日+时+分+6位随机数，如：2108111050123456。
        Long operId = 1L;//JwtUtil.getUserId();
        String projectNo = OrderUtils.getProjectNo(operId);
        // 2、拼接Redis键值：keda:import:equipType_项目编号
        String redisKey = OrderUtils.getRedisProjectNoKey(projectNo);
        String redisCountKey = OrderUtils.getRedisRecordCountKey(projectNo);
        //3、存储到reids中，有效期为30分钟。
        Map<String, Object> RedisCasgRecordMap = new HashMap<>(voList.size());
        int errorCount = 0;
        AtomicDouble totalAmount = new AtomicDouble();
        for (EquipTypeVo vo : voList
        ) {
            //获取redis自增主键
            long id = redisUtils.incr(projectNo, 1);
            //4.验证 类别信息
            EquipmenttypeEntity entity = equipmenttypeMapper.selectByName(vo.getEquipTypeName());
            if (entity != null) {
                vo.setError(true);
                vo.setVerifyResult("类别已存在");
            } else {
                vo.setError(false);
                List<String> rpList = voList.stream().map(EquipTypeVo::getEquipTypeName)
                        .collect(Collectors.toList());
                long count = rpList.stream().distinct().count();
                if (rpList.size() != count) {
                    vo.setError(true);
                    vo.setVerifyResult("类别" + vo.getEquipTypeName() + "的记录重复");
                }
            }

        }
        redisUtils.setHashMap(redisKey, RedisCasgRecordMap, OrderUtils.ORDER_EXPIRE);
        redisUtils.expire(redisCountKey, OrderUtils.ORDER_EXPIRE);
        //统计数据
        GenerateImportDto dto = new GenerateImportDto();
        dto.setErrorCount(errorCount);
        dto.setProjectNo(projectNo);
        dto.setTotalAmount(BigDecimal.valueOf(totalAmount.get()));
        dto.setTotalCount(voList.size());
        //缓存统计数据，避免保存数据时重复统计
        String statisticsKey = OrderUtils.getRedisStaticKey(projectNo);
        redisUtils.set(statisticsKey, dto, OrderUtils.ORDER_EXPIRE);
        //SaveBatch(voList);
        return dto;
    }

    /**
     * 内存导入
     * @param volist
     * @return
     */
    private int SaveBatch(List<EquipTypeVo> volist) {

        if (volist.size() == 0) {
            return -1;
        }
        //3.添加记录
        List<EquipmenttypeEntity> reqList = new ArrayList<>();
        for (Object obj : volist
        ) {
            EquipTypeVo dto = (EquipTypeVo) obj;
            //生成记录
            String json = JSON.toJSONString(dto);
            EquipmenttypeEntity record = JSON.parseObject(json, new TypeReference<EquipmenttypeEntity>() {
            });
            EquipmenttypeEntity parent = equipmenttypeMapper.selectByName(dto.getEquipTypeParentName());
            if (parent != null) {
                record.setParentId(parent.getEquipTypeId());
                record.setIsEnable(0);
                record.setCreateTime(LocalDateTime.now());
                record.setUpdateTime(LocalDateTime.now());
            } else {
                EquipmenttypeEntity father = new EquipmenttypeEntity();
                father.setEquipTypeName(dto.getEquipTypeParentName());
                father.setIsEnable(0);
                father.setParentId(0L);
                father.setCreateTime(LocalDateTime.now());
                father.setUpdateTime(LocalDateTime.now());
                equipmenttypeMapper.insert(father);
                record.setParentId(father.getEquipTypeId());
            }
            reqList.add(record);
        }
        if (reqList.size() > 0) {
            Integer iRet = equipmenttypeMapper.insertBatch(reqList);
            if (iRet > 0) {
                return 1;
            } else {
                return 0;
            }
        }
        return 0;
    }

    /**
     * redis导入数据
     * @param projectNo
     * @return
     */
    @Override
    public int SaveBatch(String projectNo) {
        String redisKey = OrderUtils.getRedisProjectNoKey(projectNo);
        String redisCountKey = OrderUtils.getRedisRecordCountKey(projectNo);
        String redisStaticKey = OrderUtils.getRedisStaticKey(projectNo);
        GenerateImportDto staticDto = (GenerateImportDto) redisUtils.get(redisStaticKey);
        if (staticDto == null) {
            return -1;
        }
        if (staticDto.getErrorCount() > 0) {
            return -2;
        }
        Integer total = (Integer) redisUtils.get(redisCountKey);
        Set<Object> ids = redisUtils.rangeZset(redisCountKey, 0, total);
        List<Object> list = redisUtils.multiGetHash(redisKey, ids);

        //3.添加记录
        List<EquipmenttypeEntity> reqList = new ArrayList<>();
        for (Object obj : list
        ) {
            EquipTypeVo dto = (EquipTypeVo) obj;
            //生成记录
            String json = JSON.toJSONString(dto);
            EquipmenttypeEntity record = JSON.parseObject(json, new TypeReference<EquipmenttypeEntity>() {
            });
            EquipmenttypeEntity parent = equipmenttypeMapper.selectByName(dto.getEquipTypeParentName());
            if (parent != null) {
                record.setParentId(parent.getEquipTypeId());
            } else {
                EquipmenttypeEntity father = new EquipmenttypeEntity();
                father.setEquipTypeName(dto.getEquipTypeParentName());
                father.setIsEnable(0);
                father.setParentId(0L);
                father.setCreateTime(LocalDateTime.now());
                father.setUpdateTime(LocalDateTime.now());
                equipmenttypeMapper.insert(father);
                record.setParentId(father.getEquipTypeId());
            }
            reqList.add(record);
        }
        if (reqList.size() > 0) {
            Integer iRet = equipmenttypeMapper.insertBatch(reqList);
            if (iRet > 0) {
                //删除redis缓存数据
                redisUtils.del(redisStaticKey);
                redisUtils.del(redisCountKey);
                redisUtils.del(redisKey);
                return 1;
            } else {
                return 0;
            }
        }
        return 0;
    }

    @Override
    public List<EquipTypeTreeVo> getTreeLazy(Long equipTypeId) {
        //查到第一层
        List<EquipTypeTreeVo> list = equipmenttypeMapper.selectAll(equipTypeId,null);

        return list;
    }

    @Override
    public List<EquipTypeTreeVo> getTree() {

        //查到第一层
        List<EquipTypeTreeVo> list = equipmenttypeMapper.selectAll(0L,null);
        list.stream().forEach(map->{
            List<EquipTypeTreeVo> child = equipmenttypeMapper.selectAll(map.getEquipTypeId(),null);
            map.setChildren(child);
        });
        return list;
    }
}
